<?php

abstract class AssociationDefinition implements IAssociationDefinition
{

  protected $associationForeignKey;

  protected $associationPrimaryKey;

  protected $associationTable;

  protected $dao;

  protected $foreignKey;

  protected $name;

  protected $primaryKey;

  protected $required;

  protected $single;

  protected $source;

  protected $target;

  protected $exclusive;

  /**
   *
   * @param string $name
   * @return void
   */
  public function __construct($source, $target, $params = array())
  {
    $this->source = $source;
    $this->target = $target;

    foreach ((array)$params as $param => $value) {
      $this->$param = $value;
    }
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getName()
   */
  public function getName()
  {
    if (empty($this->name)) {
      return $this->getTarget()->getName();
    }

    return $this->name;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getAssociationForeignKey()
   */
  public function getAssociationForeignKey()
  {
    if (empty($this->associationForeignKey)) {
      $this->associationForeignKey = $this->getForeignKey();
    }

    return $this->associationForeignKey;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getAssociationPrimaryKey()
   */
  public function getAssociationPrimaryKey()
  {
    if (empty($this->associationPrimaryKey)) {
      $this->associationPrimaryKey = $this->getPrimaryKey();
    }

    return $this->associationPrimaryKey;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getAssociationTable()
   */
  public function getAssociationTable()
  {
    if (empty($this->associationTable)) {
      $tables = array($this->getSource()->getTable(), $this->getTarget()->getTable());

      sort($tables);

      $this->associationTable = implode('_', $tables);
    }

    return $this->associationTable;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getForeignKey()
   */
  public function getForeignKey()
  {
    if (empty($this->foreignKey)) {
      return $this->getTarget()->getPk();
    }

    return $this->foreignKey;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getPrimaryKey()
   */
  public function getPrimaryKey()
  {
    if (empty($this->primaryKey)) {
      return $this->getSource()->getPk();
    }

    return $this->primaryKey;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getDAO()
   */
  public function getDAO()
  {
    if (empty($this->dao)) {
      $class = get_class($this) . 'DAO';
      $this->dao = new $class($this);
    }

    return $this->dao;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getSource()
   */
  public function getSource()
  {
    if (is_string($this->source)) {
      return Domain::getInstance()->getObject($this->source);
    }

    return $this->source;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#getTarget()
   */
  public function getTarget()
  {
    if (is_string($this->target)) {
      return Domain::getInstance()->getObject($this->target);
    }

    return $this->target;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#isRequired()
   */
  public function isRequired()
  {
    return $this->required;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#isExclusive()
   */
  public function isExclusive()
  {
    return $this->exclusive;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/domain/api/IAssociationDefinition#isSingle()
   */
  public function isSingle()
  {
    return $this->single;
  }

}

?>